1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.integration.expression;
18
19 import java.util.AbstractMap;
20 import java.util.Collection;
21 import java.util.Map;
22 import java.util.Set;
23 import java.util.stream.Collectors;
24
25 import org.springframework.expression.EvaluationContext;
26 import org.springframework.expression.Expression;
27 import org.springframework.expression.common.LiteralExpression;
28 import org.springframework.lang.Nullable;
29 import org.springframework.util.Assert;
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 public final class ExpressionEvalMap extends AbstractMap<String, Object> {
70
71 public static final EvaluationCallback SIMPLE_CALLBACK = Expression::getValue;
72
73 private final Map<String, ?> original;
74
75 private final EvaluationCallback evaluationCallback;
76
77 private ExpressionEvalMap(Map<String, ?> original, EvaluationCallback evaluationCallback) {
78 this.original = original;
79 this.evaluationCallback = evaluationCallback;
80 }
81
82
83
84
85
86 @Override
87 @Nullable
88 public Object get(Object key) {
89 Object value = this.original.get(key);
90 if (value != null) {
91 Expression expression;
92 if (value instanceof Expression) {
93 expression = (Expression) value;
94 }
95 else if (value instanceof String) {
96 expression = new LiteralExpression((String) value);
97 }
98 else {
99 throw new IllegalArgumentException("Values must be "
100 + "'java.lang.String' or 'org.springframework.expression.Expression'; the value type for key "
101 + key + " is : " + value.getClass());
102 }
103 return this.evaluationCallback.evaluate(expression);
104 }
105 return null;
106 }
107
108 @Override
109 public Set<Map.Entry<String, Object>> entrySet() {
110 return this.original.keySet()
111 .stream()
112 .map((key) -> new SimpleImmutableEntry<>(key, get(key)))
113 .collect(Collectors.toSet());
114 }
115
116 @Override
117 public Collection<Object> values() {
118 return this.original.values()
119 .stream()
120 .map(this::get)
121 .collect(Collectors.toList());
122 }
123
124 @Override
125 public boolean containsKey(Object key) {
126 return this.original.containsKey(key);
127 }
128
129 @Override
130 public Set<String> keySet() {
131 return this.original.keySet();
132 }
133
134 @Override
135 public boolean isEmpty() {
136 return this.original.isEmpty();
137 }
138
139 @Override
140 public int size() {
141 return this.original.size();
142 }
143
144 @Override
145 public boolean equals(Object o) {
146 return this.original.equals(o);
147 }
148
149 @Override
150 public int hashCode() {
151 return this.original.hashCode();
152 }
153
154 @Override
155 public String toString() {
156 return this.original.toString();
157 }
158
159 @Override
160 public Object put(String key, Object value) {
161 throw new UnsupportedOperationException();
162 }
163
164 @Override
165 public void putAll(Map<? extends String, ?> m) {
166 throw new UnsupportedOperationException();
167 }
168
169 @Override
170 public void clear() {
171 throw new UnsupportedOperationException();
172 }
173
174 @Override
175 public boolean containsValue(Object value) {
176 throw new UnsupportedOperationException();
177 }
178
179 @Override
180 public Object remove(Object key) {
181 throw new UnsupportedOperationException();
182 }
183
184
185 public static ExpressionEvalMapBuilder from(Map<String, ?> expressions) {
186 Assert.notNull(expressions, "'expressions' must not be null.");
187 return new ExpressionEvalMapBuilder(expressions);
188 }
189
190
191
192
193
194
195 @FunctionalInterface
196 public interface EvaluationCallback {
197
198 @Nullable
199 Object evaluate(Expression expression);
200
201 }
202
203
204
205
206
207
208 public static class ComponentsEvaluationCallback implements EvaluationCallback {
209
210 @Nullable
211 private final EvaluationContext context;
212
213 @Nullable
214 private final Object root;
215
216 private final boolean rootExplicitlySet;
217
218 @Nullable
219 private final Class<?> returnType;
220
221 public ComponentsEvaluationCallback(@Nullable EvaluationContext context, @Nullable Object root,
222 boolean rootExplicitlySet, @Nullable Class<?> returnType) {
223
224 this.context = context;
225 this.root = root;
226 this.rootExplicitlySet = rootExplicitlySet;
227 this.returnType = returnType;
228 }
229
230 @Override
231 public Object evaluate(Expression expression) {
232 if (this.context != null) {
233 if (this.rootExplicitlySet) {
234 return expression.getValue(this.context, this.root, this.returnType);
235 }
236 else {
237 return expression.getValue(this.context, this.returnType);
238 }
239 }
240 return expression.getValue(this.root, this.returnType);
241 }
242
243 }
244
245
246
247
248
249 public static final class ExpressionEvalMapBuilder {
250
251 private final Map<String, ?> expressions;
252
253 private EvaluationCallback evaluationCallback;
254
255 @Nullable
256 private EvaluationContext context;
257
258 @Nullable
259 private Object root;
260
261 private boolean rootExplicitlySet;
262
263 @Nullable
264 private Class<?> returnType;
265
266 private final ExpressionEvalMapComponentsBuilder evalMapComponentsBuilder =
267 new ExpressionEvalMapComponentsBuilderImpl();
268
269 private final ExpressionEvalMapFinalBuilder finalBuilder = new ExpressionEvalMapFinalBuilderImpl();
270
271 private ExpressionEvalMapBuilder(Map<String, ?> expressions) {
272 this.expressions = expressions;
273 }
274
275 public ExpressionEvalMapFinalBuilder usingCallback(EvaluationCallback callback) {
276 this.evaluationCallback = callback;
277 return this.finalBuilder;
278 }
279
280 public ExpressionEvalMapFinalBuilder usingSimpleCallback() {
281 return this.usingCallback(SIMPLE_CALLBACK);
282 }
283
284 public ExpressionEvalMapComponentsBuilder usingEvaluationContext(EvaluationContext context) {
285 this.context = context;
286 return this.evalMapComponentsBuilder;
287 }
288
289 public ExpressionEvalMapComponentsBuilder withRoot(@Nullable Object root) {
290 this.root = root;
291 this.rootExplicitlySet = true;
292 return this.evalMapComponentsBuilder;
293
294 }
295
296 public ExpressionEvalMapComponentsBuilder withReturnType(Class<?> returnType) {
297 this.returnType = returnType;
298 return this.evalMapComponentsBuilder;
299
300 }
301
302
303 private class ExpressionEvalMapFinalBuilderImpl implements ExpressionEvalMapFinalBuilder {
304
305 ExpressionEvalMapFinalBuilderImpl() {
306 }
307
308 @Override
309 public ExpressionEvalMap build() {
310 if (ExpressionEvalMapBuilder.this.evaluationCallback != null) {
311 return new ExpressionEvalMap(ExpressionEvalMapBuilder.this.expressions,
312 ExpressionEvalMapBuilder.this.evaluationCallback);
313 }
314 else {
315 return new ExpressionEvalMap(ExpressionEvalMapBuilder.this.expressions,
316 new ComponentsEvaluationCallback(ExpressionEvalMapBuilder.this.context,
317 ExpressionEvalMapBuilder.this.root, ExpressionEvalMapBuilder.this.rootExplicitlySet,
318 ExpressionEvalMapBuilder.this.returnType));
319 }
320 }
321
322 }
323
324
325 private class ExpressionEvalMapComponentsBuilderImpl extends ExpressionEvalMapFinalBuilderImpl
326 implements ExpressionEvalMapComponentsBuilder {
327
328 ExpressionEvalMapComponentsBuilderImpl() {
329 }
330
331 @Override
332 public ExpressionEvalMapComponentsBuilder usingEvaluationContext(EvaluationContext context) {
333 return ExpressionEvalMapBuilder.this.usingEvaluationContext(context);
334 }
335
336 @Override
337 public ExpressionEvalMapComponentsBuilder withRoot(@Nullable Object root) {
338 return ExpressionEvalMapBuilder.this.withRoot(root);
339 }
340
341 @Override
342 public ExpressionEvalMapComponentsBuilder withReturnType(Class<?> returnType) {
343 return ExpressionEvalMapBuilder.this.withReturnType(returnType);
344 }
345
346 }
347
348 }
349
350 @FunctionalInterface
351 public interface ExpressionEvalMapFinalBuilder {
352
353 ExpressionEvalMap build();
354
355 }
356
357
358 public interface ExpressionEvalMapComponentsBuilder extends ExpressionEvalMapFinalBuilder {
359
360 ExpressionEvalMapComponentsBuilder usingEvaluationContext(EvaluationContext context);
361
362 ExpressionEvalMapComponentsBuilder withRoot(@Nullable Object root);
363
364 ExpressionEvalMapComponentsBuilder withReturnType(Class<?> returnType);
365
366 }
367
368 }